#include "gtest/gtest.h"

#include "Topic.h"
#include "recovery/Block.h"
#include "recovery/fs/file/FileLogOperation.h"
#include "ILog.h"
using recovery::fs::file::FileLogOperation;

//TODO: ReadFromStart
//TODO: ReaderFromIndex

class Reader {
public:
    Reader(Topic & topic)
    : _topic(topic) 
    , _meta(IMeta::create(topic))
    {
    }
    ~Reader(){}

    recovery::Status open(){
        if(_topic.open() == 0){
            if(!FileLogOperation::exist(_topic.logPath())) 
                return recovery::Status::Failed("log fail is not exist, can not start reader");

            auto s = FileLogOperation::openExist(_topic.logPath(), _log).toStatus();
            if(!s) return s;

            size_t logFileSize = 0;
            s = _log->size(logFileSize).toStatus();
            if(!s) return s;

            s =_meta->open();
            if(!s) return s;

            s = _meta->load();
            if(!s)  return s;

            if(logFileSize > _meta->logSize().value()){
                s = _log->truncate(_meta->logSize().value()).toStatus();
                if(!s) return s;
            }
            // assert  logFileSize == meta->logSize
            return recovery::Status::OK();
        }
        return recovery::Status::Failed("open topic failed");
    }

    recovery::Status close(){
        _topic.close();
        return recovery::Status::OK();
    }

    bool hasNext() const{
        return _readOffset < _meta->logSize().value();
    }
    std::pair<long long, std::string> next(){
        while(_readOffset < _meta->logSize().value()){
            // 0. check the bytes_in_buffer > sizeof(record_header)
            // 1. if false 
                // 1. readBlock(); -> [bytes_in_buffer_start, bytes_in_buffer_end];
            
            // 2. get record header 
            // 3. get record body
            // 4. offset += record.size();
            //TODO:
        }
        return std::make_pair(1, std::string("hello world"));
    }

private:
    Topic & _topic;
	IMeta * _meta;
    std::unique_ptr<recovery::fs::file::FileLogOperation> _log;
    recovery::Block block;
    size_t _readOffset = 0;
};

TEST(ReaderTest, testMain){
    Topic topic("stream", ".");
    Reader reader(topic);

    ASSERT_TRUE(reader.open());

    while(reader.hasNext()){
        auto rec = reader.next();
        ASSERT_TRUE(rec.first > 0); 
        ASSERT_TRUE(rec.second.size() >= 0);
    }
    ASSERT_TRUE(reader.close());
}


